package org.lc.service.system.component;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.lc.platform.base.util.SmEncryptUtil;
import org.lc.service.system.config.InitSystemDataConfig;
import org.lc.service.system.entity.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 容器启动完成加载资源权限数据到缓存
 *
 * @author ls
 */
@Slf4j
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Component
public class InitSystemRunner implements CommandLineRunner {
    @Resource
    InitSystemDataConfig initSystemDataConfig;

    @Override
    @Transactional
    public void run(String... args) {
        var wrap = Db.lambdaQuery(SysUser.class).eq(SysUser::getAccount, initSystemDataConfig.getDefaultAccount());
        var user = wrap.one();
        if (ObjUtil.isNull(user)) {
            initUserAndRole();
            initDict();
            initParentMenu();
        }
    }

    public void initDict() {
        var lDict = new SysDict();
        lDict.setCode("logger_type");
        lDict.setName("日志分类");
        var tDict = new SysDict();
        tDict.setCode("data_type");
        tDict.setName("数据类型");
        log.info(String.valueOf(tDict));
        Db.saveBatch(List.of(lDict, tDict));
        log.info(tDict.getId());
        log.info(lDict.getId());
        List<SysDictDetail> arrDetail = new ArrayList<>();
        arrDetail.add(new SysDictDetail(lDict.getId(), "登录日志", "login", 1));
        arrDetail.add(new SysDictDetail(lDict.getId(), "异常日志", "exception", 2));
        arrDetail.add(new SysDictDetail(lDict.getId(), "操作日志", "handle", 3));
        arrDetail.add(new SysDictDetail(lDict.getId(), "其他日志", "other", 4));
        arrDetail.add(new SysDictDetail(tDict.getId(), "字符", "string", 1));
        arrDetail.add(new SysDictDetail(tDict.getId(), "布尔", "boolean", 2));
        arrDetail.add(new SysDictDetail(tDict.getId(), "整数", "int", 3));
        arrDetail.add(new SysDictDetail(tDict.getId(), "浮点", "float", 4));
        arrDetail.add(new SysDictDetail(tDict.getId(), "对象", "json", 5));
        arrDetail.add(new SysDictDetail(tDict.getId(), "日期", "date", 6));
        arrDetail.add(new SysDictDetail(tDict.getId(), "空值", "empty", 7));
        Db.saveBatch(arrDetail);
    }

    public void initParentMenu() {
        var menu = new SysMenu();
        menu.setIsLeaf(false);
        menu.setSort(1);
        menu.setIcon("ant-design:setting-filled");
        menu.setText("系统管理");
        menu.setTitle("系统");
        menu.setRemark("系统管理");
        Db.save(menu);
        initMenuManage(menu.getId());
        initUserManage(menu.getId());
        initRoleManage(menu.getId());
        initDepartmentManage(menu.getId());
        initLogManage(menu.getId());
        initDictManage(menu.getId());
    }

    private void initMenuManage(String parentId) {
        var menu = new SysMenu();
        menu.setParentId(parentId);
        menu.setIsLeaf(true);
        menu.setSort(3);
        menu.setIcon("ant-design:menu-outlined");
        menu.setRouter("/backstage/system/menu");
        menu.setText("菜单管理");
        menu.setRemark("菜单管理");
        menu.setTitle("菜单");
        menu.setPath("menu");
        Db.save(menu);
        List<SysPermission> permissions = new ArrayList<>();
        permissions.add(new SysPermission(menu.getId(), "权限查看", "permission_get"));
        permissions.add(new SysPermission(menu.getId(), "权限修改", "permission_patch"));
        permissions.add(new SysPermission(menu.getId(), "新增权限", "permission_post"));
        permissions.add(new SysPermission(menu.getId(), "权限删除", "permission_delete"));
        permissions.add(new SysPermission(menu.getId(), "API列表", "get_api_list"));
        permissions.add(new SysPermission(menu.getId(), "新增", initSystemDataConfig.getCreateCode()));
        permissions.add(new SysPermission(menu.getId(), "删除", initSystemDataConfig.getDeleteCode()));
        permissions.add(new SysPermission(menu.getId(), "更新", initSystemDataConfig.getUpdateCode()));
        permissions.add(new SysPermission(menu.getId(), "获取", initSystemDataConfig.getGetCode()));
        Db.saveBatch(permissions);
    }

    private void initUserManage(String parentId) {
        var menu = new SysMenu();
        menu.setParentId(parentId);
        menu.setIsLeaf(true);
        menu.setSort(1);
        menu.setIcon("ant-design:user-outlined");
        menu.setRouter("/backstage/system/user");
        menu.setText("用户管理");
        menu.setTitle("用户");
        menu.setRemark("用户管理");
        menu.setPath("user");
        Db.save(menu);
        List<SysPermission> permissions = new ArrayList<>();
        permissions.add(new SysPermission(menu.getId(), "密码修改", "update_password"));
        permissions.add(new SysPermission(menu.getId(), "重置缓存", "reset_acl"));
        permissions.add(new SysPermission(menu.getId(), "强制下线", "need_logout"));
        permissions.add(new SysPermission(menu.getId(), "消息通知", "msg_notice"));
        permissions.add(new SysPermission(menu.getId(), "部门列表", "get_department_list"));
        permissions.add(new SysPermission(menu.getId(), "角色列表", "get_role_list"));
        permissions.add(new SysPermission(menu.getId(), "新增", initSystemDataConfig.getCreateCode()));
        permissions.add(new SysPermission(menu.getId(), "删除", initSystemDataConfig.getDeleteCode()));
        permissions.add(new SysPermission(menu.getId(), "批量删除", initSystemDataConfig.getDeleteManyCode()));
        permissions.add(new SysPermission(menu.getId(), "获取", initSystemDataConfig.getGetCode()));
        permissions.add(new SysPermission(menu.getId(), "更新", initSystemDataConfig.getUpdateCode()));
        permissions.add(new SysPermission(menu.getId(), "导入", initSystemDataConfig.getImportCode()));
        permissions.add(new SysPermission(menu.getId(), "导出", initSystemDataConfig.getExportCode()));
        Db.saveBatch(permissions);
    }

    private void initRoleManage(String parentId) {
        var menu = new SysMenu();
        menu.setParentId(parentId);
        menu.setIsLeaf(true);
        menu.setSort(2);
        menu.setIcon("ant-design:user-add-outlined");
        menu.setRouter("/backstage/system/role");
        menu.setText("角色管理");
        menu.setTitle("角色");
        menu.setRemark("角色管理");
        menu.setPath("role");
        Db.save(menu);
        List<SysPermission> permissions = new ArrayList<>();
        permissions.add(new SysPermission(menu.getId(), "清除角色缓存", "clear_storge"));
        permissions.add(new SysPermission(menu.getId(), "获取访问权限", "acl_get"));
        permissions.add(new SysPermission(menu.getId(), "更新访问权限", "patch_acl"));
        permissions.add(new SysPermission(menu.getId(), "获取接口权限", "acl_api_get"));
        permissions.add(new SysPermission(menu.getId(), "更新接口权限", "acl_api_update"));
        permissions.add(new SysPermission(menu.getId(), "删除", initSystemDataConfig.getDeleteCode()));
        permissions.add(new SysPermission(menu.getId(), "新增", initSystemDataConfig.getCreateCode()));
        permissions.add(new SysPermission(menu.getId(), "获取", initSystemDataConfig.getGetCode()));
        permissions.add(new SysPermission(menu.getId(), "更新", initSystemDataConfig.getUpdateCode()));
        permissions.add(new SysPermission(menu.getId(), "批量删除", initSystemDataConfig.getDeleteManyCode()));
        permissions.add(new SysPermission(menu.getId(), "导入", initSystemDataConfig.getImportCode()));
        permissions.add(new SysPermission(menu.getId(), "导出", initSystemDataConfig.getExportCode()));
        Db.saveBatch(permissions);
    }

    private void initDepartmentManage(String parentId) {
        var menu = new SysMenu();
        menu.setParentId(parentId);
        menu.setIsLeaf(true);
        menu.setSort(5);
        menu.setIcon("ant-design:apartment-outlined");
        menu.setRouter("/backstage/system/department");
        menu.setText("组织管理");
        menu.setTitle("组织");
        menu.setRemark("组织管理");
        menu.setPath("department");
        Db.save(menu);
        List<SysPermission> permissions = new ArrayList<>();
        permissions.add(new SysPermission(menu.getId(), "获取部门人员列表", "department_get_user_list"));
        permissions.add(new SysPermission(menu.getId(), "人员删除", "department_del_user"));
        permissions.add(new SysPermission(menu.getId(), "人员添加", "department_add_user"));
        permissions.add(new SysPermission(menu.getId(), "获取", initSystemDataConfig.getGetCode()));
        permissions.add(new SysPermission(menu.getId(), "更新", initSystemDataConfig.getUpdateCode()));
        permissions.add(new SysPermission(menu.getId(), "新增", initSystemDataConfig.getCreateCode()));
        permissions.add(new SysPermission(menu.getId(), "批量删除", initSystemDataConfig.getDeleteManyCode()));
        Db.saveBatch(permissions);
    }

    private void initLogManage(String parentId) {
        var menu = new SysMenu();
        menu.setParentId(parentId);
        menu.setIsLeaf(true);
        menu.setSort(6);
        menu.setIcon("ant-design:file-search-outlined");
        menu.setRouter("/backstage/system/logger");
        menu.setTitle("日志");
        menu.setText("日志管理");
        menu.setRemark("日志管理");
        menu.setPath("logger");
        Db.save(menu);
        List<SysPermission> permissions = new ArrayList<>();
        permissions.add(new SysPermission(menu.getId(), "详情操作", "logger_detail"));
        permissions.add(new SysPermission(menu.getId(), "获取", initSystemDataConfig.getGetCode()));
        permissions.add(new SysPermission(menu.getId(), "导入", initSystemDataConfig.getImportCode()));
        permissions.add(new SysPermission(menu.getId(), "导出", initSystemDataConfig.getExportCode()));
        permissions.add(new SysPermission(menu.getId(), "批量删除", initSystemDataConfig.getDeleteManyCode()));
        Db.saveBatch(permissions);
    }

    private void initDictManage(String parentId) {
        var menu = new SysMenu();
        menu.setParentId(parentId);
        menu.setIsLeaf(true);
        menu.setSort(7);
        menu.setIcon("ant-design:read-outlined");
        menu.setRouter("/backstage/system/dict");
        menu.setText("字典管理");
        menu.setTitle("字典");
        menu.setRemark("字典管理");
        menu.setPath("dict");
        Db.save(menu);
        List<SysPermission> permissions = new ArrayList<>();
        permissions.add(new SysPermission(menu.getId(), "新增详情", "add_detail"));
        permissions.add(new SysPermission(menu.getId(), "详情列表", "get_detail_list"));
        permissions.add(new SysPermission(menu.getId(), "删除详情", "delete_detail"));
        permissions.add(new SysPermission(menu.getId(), "批量删除详情", "delete_many_detail"));
        permissions.add(new SysPermission(menu.getId(), "更新详情", "update_detail"));
        permissions.add(new SysPermission(menu.getId(), "新增", initSystemDataConfig.getCreateCode()));
        permissions.add(new SysPermission(menu.getId(), "获取", initSystemDataConfig.getGetCode()));
        permissions.add(new SysPermission(menu.getId(), "删除", initSystemDataConfig.getDeleteCode()));
        permissions.add(new SysPermission(menu.getId(), "更新", initSystemDataConfig.getUpdateCode()));
        permissions.add(new SysPermission(menu.getId(), "批量删除", initSystemDataConfig.getDeleteManyCode()));
        Db.saveBatch(permissions);
    }

    public void initUserAndRole() {
        var userId = initAccount();
        var roleId = initRole();
        var roleAndUser = new SysRoleUser(roleId, userId);
        Db.save(roleAndUser);
        initDepartment(userId);
    }

    private void initDepartment(String userId) {
        var department = new SysDepartment();
        department.setTitle("系统管理部");
        department.setIcon("carbon:cics-system-group");
        department.setIsLeaf(false);
        department.setSort(1);
        department.setRemark("系统管理部门，主要负责系统管理");
        Db.save(department);
        var du = new SysDepartmentUser(userId, department.getId());
        Db.save(du);
    }

    private String initAccount() {
        var user = new SysUser();
        user.setAccount(initSystemDataConfig.getDefaultAccount());
        user.setName("默认管理员-自动创建");
        user.setPassword(SmEncryptUtil.passWordEncrypt(initSystemDataConfig.getDefaultPassword()));
        Db.save(user);
        return user.getId();
    }

    private String initRole() {
        var role = new SysRole();
        role.setCode(initSystemDataConfig.getDefaultRole());
        role.setName("超级管理员-自动创建");
        role.setRemark("超级管理员的角色");
        Db.save(role);
        return role.getId();
    }
}


